package com.vidmt.api.modules.sys.auth.pwdstrategy;

import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.Random;

import javax.security.sasl.SaslException;
import javax.xml.bind.DatatypeConverter;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.vidmt.api.common.utils.Blowfish;

public class ScramStrategy extends BlowfishStrategy {
	private static Logger log = LoggerFactory.getLogger(ScramStrategy.class);
	private static final Random random = new Random();

	public static void main(String[] args) {
		byte[] saltShaker = DatatypeConverter.parseBase64Binary("4Ab7yqZf8lAz/s+MPly5Kw/cdrkjkUHeK5hhWfsGOKA=");
		String salt = DatatypeConverter.printBase64Binary(saltShaker);
		System.out.println(salt);

		int iterations = ScramUtils.DEFAULT_ITERATION_COUNT;
		// JiveGlobals.getIntProperty("sasl.scram-sha-1.iteration-count",
		// ScramUtils.DEFAULT_ITERATION_COUNT);
		byte[] saltedPassword = null, clientKey = null, storedKey = null, serverKey = null;
		try {
			saltedPassword = ScramUtils.createSaltedPassword(saltShaker, "123456", iterations);
			clientKey = ScramUtils.computeHmac(saltedPassword, "Client Key");
			storedKey = MessageDigest.getInstance("SHA-1").digest(clientKey);
			serverKey = ScramUtils.computeHmac(saltedPassword, "Server Key");
		} catch (SaslException | NoSuchAlgorithmException e) {
			log.warn("Unable to persist values for SCRAM authentication.", e);
		}

		String storedKeyStr = DatatypeConverter.printBase64Binary(storedKey);
		String serverKeyStr = DatatypeConverter.printBase64Binary(serverKey);
		String keyString = String.format("%s@%s@%s@%s@%s", "1qaz2wsx", storedKeyStr, serverKeyStr, salt, iterations);
		System.out.println(keyString);

		Blowfish bf = new Blowfish("1qaz2wsx");
		System.out.println(bf.encryptString("123456"));
		System.out.println(bf.decryptString("772e1b9bf3b651941ce0cb6efc0a6071"));
	}

	@Override
	public String fmtKey(String rawkey,String plainpwd) {
		byte[] saltShaker = new byte[32];
		random.nextBytes(saltShaker);
		// byte[] saltShaker =
		// DatatypeConverter.parseBase64Binary("4Ab7yqZf8lAz/s+MPly5Kw/cdrkjkUHeK5hhWfsGOKA=");
		// plainpwd="123456";

		int iterations = ScramUtils.DEFAULT_ITERATION_COUNT;
		// JiveGlobals.getIntProperty("sasl.scram-sha-1.iteration-count",
		// ScramUtils.DEFAULT_ITERATION_COUNT);
		byte[] saltedPassword = null, clientKey = null, storedKey = null, serverKey = null;
		try {
			saltedPassword = ScramUtils.createSaltedPassword(saltShaker, plainpwd, iterations);
			clientKey = ScramUtils.computeHmac(saltedPassword, "Client Key");
			storedKey = MessageDigest.getInstance("SHA-1").digest(clientKey);
			serverKey = ScramUtils.computeHmac(saltedPassword, "Server Key");
		} catch (SaslException | NoSuchAlgorithmException e) {
			log.warn("Unable to persist values for SCRAM authentication.", e);
		}

		String salt = DatatypeConverter.printBase64Binary(saltShaker);
		String storedKeyStr = DatatypeConverter.printBase64Binary(storedKey);
		String serverKeyStr = DatatypeConverter.printBase64Binary(serverKey);
		return String.format("%s@%s@%s@%s@%s", rawkey, storedKeyStr, serverKeyStr, salt, iterations);
	}

	@Override
	public String defmtKey(String fmtkey) {
		return fmtkey.split("@")[0];
	}

}
